#ifndef GAMEENGINE_CORE_MACRO_SINGLETON_H
#define GAMEENGINE_CORE_MACRO_SINGLETON_H


//! Define functions associated to a singleton class
/*!
 *  This macro creates ways to access the single instance of a singleton class. The
 *  copy constructor and assignment operators are also defined as private to forbid
 *  their use.
 *
 @note A singleton class defines an object whose instance is unique
 @note A singleton class MUST NOT reimplement a copy constructor and
       an assignment operator.
 */
#ifndef DOXYGEN_IGNORE
#define GAMEENGINE_DECLARE_SINGLETON(class_name)\
	public:\
		/*! @brief Accessor to the single instance of class class_name. */ \
		/*! @details The single instance of class class_name is built if it did not already exist. */ \
		static class_name* instance();\
	\
	private:\
		/*! @brief The single instance of class class_name. */ \
		static class_name* instance_;\
		\
		/*! @brief Copy constructor is defined as private to forbid the copy of the class_name instance. */ \
		class_name(const class_name& rhs);\
		/*! @brief Assignment operator is defined as private to forbid the copy of the class_name instance. */ \
		class_name& operator=(const class_name& rhs);
#else
#define GAMEENGINE_DECLARE_SINGLETON(class_name)\
	public:\
		/*! @brief Accessor to the single instance of class class_name. */ \
		/*! @details The single instance of class class_name is built if it did not already exist. */ \
		static class_name* instance() {\
			if ( instance_ == nil ) {\
				instance_ = new class_name();\
			}\
			return instance_;\
		}\
	\
	private:\
		/*! @brief Copy constructor is defined as private to forbid the copy of the class_name instance. */ \
		class_name(const class_name& rhs);\
		/*! @brief Assignment operator is defined as private to forbid the copy of the class_name instance. */ \
		class_name& operator=(const class_name& rhs);
#endif


//! Implementation of functions associated to a singleton class
/*!
 @note A singleton class defines an object whose instance is unique
 @note A singleton class MUST NOT reimplement a copy constructor and
       an assignment operator. Hence, these functions are declared in
	   private and never implemented to forbid their use.
 */
#ifndef DOXYGEN_IGNORE
#define GAMEENGINE_IMPLEMENT_SINGLETON(class_name)\
	class_name* class_name::instance_ = nil;\
	\
	class_name* class_name::instance() {\
		if ( instance_ == nil ) {\
			instance_ = new class_name();\
		}\
		return instance_;\
	}
#else
#define GAMEENGINE_IMPLEMENT_SINGLETON(class_name)
#endif


//! Implementation of functions associated to a singleton template class
/*!
 @note A singleton class defines an object whose instance is unique
 @note A singleton class MUST NOT reimplement a copy constructor and
       an assignment operator. Hence, these functions are declared in
	   private and never implemented to forbid their use.
 */
#ifndef DOXYGEN_IGNORE
#define GAMEENGINE_IMPLEMENT_TEMPLATE_SINGLETON(class_name)\
	class_name* class_name::instance_ = nil;\
	\
	template<> \
	class_name* class_name::instance() {\
		if ( instance_ == nil ) {\
			instance_ = new class_name();\
		}\
		return instance_;\
	}
#else
#define GAMEENGINE_IMPLEMENT_TEMPLATE_SINGLETON(class_name)
#endif

#endif
